package com.ruoyi.oa.invoker;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.ruoyi.oa.config.JinZhiConfig;
import com.ruoyi.oa.enums.JinZhiApiEnum;
import com.ruoyi.oa.invoker.pojo.dto.JinZhiCallRequest;
import com.ruoyi.oa.invoker.pojo.vo.JinZhiResponseVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Map;

/**
 * 金智OpenApi调用者
 *
 * @author ccc
 * @date 2025-3-3
 */
@Slf4j
@Component
public class JinZhiOpenApiInvoker {

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private JinZhiConfig jinzhiConfig;

    /**
     * 执行请求操作
     *
     * @return jsonObject
     * @Param jinZhiCallRequest
     */
    public JinZhiResponseVO invoke(JinZhiCallRequest jinZhiCallRequest){
        //获取http协议
        JinZhiApiEnum jinZhiApiEnum = jinZhiCallRequest.getJinZhiApiEnum();
        String url = jinzhiConfig.getDomain() + jinZhiApiEnum.getUrl();
        String apiName = jinZhiApiEnum.getApiName();
        Map<String, Object> requestParams = jinZhiCallRequest.getParams();
        HttpHeaders header = getHeader();
        HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestParams, header);

        log.info("转接层调用金智OpenApi, 接口：{}，请求参数：{}，Url:{}", apiName, JSONUtil.toJsonStr(request), url);
        ResponseEntity<JinZhiResponseVO> responseEntity = null;
        // 处理 GET 请求，将参数添加到 URL 查询字符串中
        if(HttpMethod.GET.equals(HttpMethod.GET) && requestParams != null && !requestParams.isEmpty()){
            StringBuilder queryString = new StringBuilder();
            queryString.append("?");
            for (Map.Entry<String, Object> entry : requestParams.entrySet()) {
                queryString.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
            // 移除最后一个多余的 &
            queryString.deleteCharAt(queryString.length() - 1);
            url += queryString.toString();
        }
        responseEntity = restTemplate.exchange(url, jinZhiApiEnum.getMethod(), request, JinZhiResponseVO.class);
        log.info("转接层调用金智OpenApi, 接口：{}，返回结果：{}", apiName, JSONUtil.toJsonStr(responseEntity));

        if (!ObjectUtil.equals(HttpStatus.OK, responseEntity.getStatusCode())) {
            throw new RuntimeException("转接层调用金智OpenApi, 接口：" + apiName + "接口,服务器错误");
        }

        // 解析返参数据
        JinZhiResponseVO responseBody = responseEntity.getBody();
        log.info("请求教学资源平台获取上课记录,返参:"+ responseBody);
        // 接口处理正确与否
        if(ObjectUtil.isNotEmpty(responseBody.getErrcode())){
            throw new RuntimeException("转接层调用金智OpenApi, 接口：" + apiName + "接口,返回错误信息：" + responseBody.getErrmsg());
        }
        return responseBody;
    }


    /**
     * 获取header头信息
     */
    private HttpHeaders getHeader() {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json");
        headers.add("appId", jinzhiConfig.getAppId());
        // 当前时间戳（毫秒级）
        String nowTimeStamp = String.valueOf(System.currentTimeMillis());
        headers.add("timestamp", nowTimeStamp);
        //获取加密sign
        String sign = this.generateSign(jinzhiConfig.getAppId(),jinzhiConfig.getAppSecret(), nowTimeStamp);
        headers.add("sign", sign);
        return headers;
    }

    /**
     * 生成加密字符串
     */
    private  String generateSign(String appId, String appSecret, String timestamp) {
        String input = appId + appSecret + timestamp;
        // 加密字符串
        String sign = null;
        try {
            // 计算 MD5 哈希值
            String hash = this.md5(input);
            // 使用 Base64 编码
            sign = this.base64Encode(hash);
        } catch (NoSuchAlgorithmException e) {
            log.error("NoSuchAlgorithmException", e);
            throw new RuntimeException(e);
        }
        return sign;
    }

    // 计算 MD5 哈希值的方法
    private static String md5(String inputData) throws NoSuchAlgorithmException {
        // 获取MD5摘要算法的 MessageDigest 对象
        MessageDigest digest = MessageDigest.getInstance("MD5");
        // 对字符串的字节流数据进行更新
        byte[] bytes = digest.digest(inputData.getBytes());
        // 将得到的字节数组变成字符串返回
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xFF & b);
            if (hex.length() == 1) {
                sb.append('0');
            }
            sb.append(hex);
        }
        return sb.toString();
    }

    // Base64 编码的方法
    private  static String base64Encode(String inputData) {
        byte[] bytes = inputData.getBytes(StandardCharsets.UTF_8);
        return Base64.getEncoder().encodeToString(bytes);
    }


    public static void main(String[] args) throws NoSuchAlgorithmException {

        /**
         * 应用程序id
         */
        String appId = "1894308183108587522";

        /**
         * 应用程序密钥
         */
        String appSecret = "147d6bad875f49d3a779d6520081cebb";

        String input = appId + appSecret + "1741252238903";
        // 加密字符串
        String sign = null;
        try {
            // 计算 MD5 哈希值
            String hash = md5(input);
            System.out.printf("hash:"+hash);
            System.out.printf("\n");
            // 使用 Base64 编码
            sign = base64Encode(hash);
            System.out.printf("sign:"+sign);
            System.out.printf("\n");
        } catch (NoSuchAlgorithmException e) {
            log.error("NoSuchAlgorithmException", e);
            throw new RuntimeException(e);
        }
    }
}
